// A* 寻路算法的 JavaScript 实现
const MAX_PATH_LENGTH = 10000;
const MAX_OPEN_LIST = 100000;
const STRAIGHT_COST = 10;
const DIAGONAL_COST = 14;
const DIRECTION_CHANGE_PENALTY = 5;  // 转向惩罚

// 方向数组：右上和左下优先，左上和右下次之，直线移动
const DIRECTIONS = [
    [1, -1], [-1, 1], [1, 1], [-1, -1],    // 对角线移动优先
    [1, 0], [0, -1], [-1, 0], [0, 1]       // 直线移动次之
];

class Node {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        this.F = 0;
        this.G = 0;
        this.H = 0;
        this.parent = null;
        this.visited = 0;  // 0: 未访问, 1: 开放列表, 2: 关闭列表
        this.direction = -1;  // 记录移动方向
    }
}

class AStar {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    // 更新网格数据（支持二维数组）
    updateGrid(gridData, width, height) {
        this.width = width;
        this.height = height;
		
		//初始化。
		this.grid = new Int32Array(width * height);
        this.nodes = new Array(width * height);
        this.openList = [];
        this.openListCount = 0;
        this.maxIterations = width * height * 4;

        // 初始化节点数组
        for (let i = 0; i < width * height; i++) {
            this.nodes[i] = new Node(0, 0);
        }
		
        if (Array.isArray(gridData) && Array.isArray(gridData[0])) {
            // 外层是x，内层是y
            for (let x = 0; x < this.width; x++) {
                const col = gridData[x] || [];
                for (let y = 0; y < this.height; y++) {
                    //this.grid[y * this.width + x] = col[y] !== undefined ? col[y] : 0;
                    this.grid[y * this.width + x] = !(col[y]) ? 0 : 1;
                    //gridHeap[index] = (!(grid[x][y]) ? 0 : 1);  // 0表示可通行，1表示障碍
                }
            }
        } else {
            this.grid.set(gridData);
        }
    }

    // 获取节点索引
    getNodeIndex(x, y) {
        return y * this.width + x;
    }

    // 计算H值（考虑对角线移动）
    calculateH(x1, y1, x2, y2) {
        const dx = Math.abs(x2 - x1);
        const dy = Math.abs(y2 - y1);
        return DIAGONAL_COST * Math.min(dx, dy) + STRAIGHT_COST * Math.abs(dx - dy);
    }

    // 添加到开放列表
    addToOpenList(node) {
        this.openList[this.openListCount++] = node;
    }

    // 从开放列表中移除
    removeFromOpenList(index) {
        this.openList[index] = this.openList[--this.openListCount];
    }

    // 查找最小F值的节点
    findMinFNode() {
        let minF = this.openList[0].F;
        let minIndex = 0;
        
        for (let i = 1; i < this.openListCount; i++) {
            if (this.openList[i].F < minF) {
                minF = this.openList[i].F;
                minIndex = i;
            }
        }
        
        return minIndex;
    }

    // 获取方向索引
    getDirectionIndex(dx, dy) {
        for (let i = 0; i < 8; i++) {
            if (DIRECTIONS[i][0] === dx && DIRECTIONS[i][1] === dy) {
                return i;
            }
        }
        return -1;
    }

    // 计算方向变化的代价
    calculateDirectionChangeCost(current, newDirection) {
        if (!current.parent) return 0;
        
        const parentDx = current.x - current.parent.x;
        const parentDy = current.y - current.parent.y;
        const parentDirection = this.getDirectionIndex(parentDx, parentDy);
        
        return (parentDirection !== newDirection) ? DIRECTION_CHANGE_PENALTY : 0;
    }

    // 检查移动是否有效
    isValidMove(fromX, fromY, toX, toY) {
        // 检查边界
        if (toX < 0 || toX >= this.width || toY < 0 || toY >= this.height) {
            return false;
        }
        
        // 检查目标点是否可通行
        if (this.grid[this.getNodeIndex(toX, toY)] !== 0) {
            return false;
        }
        
        // 计算移动方向
        const dx = toX - fromX;
        const dy = toY - fromY;
        
        // 如果是直线移动，直接返回true
        if (dx === 0 || dy === 0) {
            return true;
        }
		
		// 对于对角线移动，只检查目标点是否可达
		return 1;//
        
        // 对于对角线移动，检查相邻点
        const straightX = this.grid[this.getNodeIndex(fromX + dx, fromY)];
        const straightY = this.grid[this.getNodeIndex(fromX, fromY + dy)];
        
        // 如果至少有一个相邻点可以通行，就允许对角线移动
        return straightX === 0 || straightY === 0;
    }

    // 查找路径
    findPath(startX, startY, endX, endY) {
        console.log(`寻路开始: 从(${startX}, ${startY})到(${endX}, ${endY})`);

        // 重置状态
        this.openListCount = 0;
        for (let i = 0; i < this.width * this.height; i++) {
            this.nodes[i].visited = 0;
            this.nodes[i].parent = null;
        }

        // 检查起点和终点是否有效
        if (startX < 0 || startX >= this.width || startY < 0 || startY >= this.height ||
            endX < 0 || endX >= this.width || endY < 0 || endY >= this.height) {
            self.postMessage("message_坐标超出范围");
            return null;
        }

        // 检查起点和终点是否可通行
        if (this.grid[this.getNodeIndex(startX, startY)] !== 0 ||
            this.grid[this.getNodeIndex(endX, endY)] !== 0) {
            self.postMessage("message_起点或终点不可通行");
            return null;
        }

        // 创建起始节点
        const startNode = this.nodes[this.getNodeIndex(startX, startY)];
        startNode.x = startX;
        startNode.y = startY;
        startNode.G = 0;
        startNode.H = this.calculateH(startX, startY, endX, endY);
        startNode.F = startNode.G + startNode.H;
        startNode.parent = null;
        startNode.visited = 1;

        // 添加起始节点到开放列表
        this.addToOpenList(startNode);

        let iterations = 0;
        while (this.openListCount > 0 && iterations < this.maxIterations) {
            iterations++;
            
            // 获取F值最小的节点
            const currentIndex = this.findMinFNode();
            const currentNode = this.openList[currentIndex];

            // 到达目标
            if (currentNode.x === endX && currentNode.y === endY) {
                // 构建路径
                const path = [];
                let node = currentNode;

                while (node) {
                    if (path.length >= MAX_PATH_LENGTH) {
                        self.postMessage("message_路径太长");
                        return null;
                    }
                    path.unshift([node.x, node.y]);
                    node = node.parent;
                }

                //console.log(`寻路结束: 成功 - 找到路径，长度: ${path.length}`);
				self.postMessage("message_寻路结束: 成功 - 找到路径，长度:"+path.length);
                return path;
            }

            // 将当前节点移到关闭列表
            this.removeFromOpenList(currentIndex);
            currentNode.visited = 2;

            // 检查相邻节点
            for (let i = 0; i < 8; i++) {
                const newX = currentNode.x + DIRECTIONS[i][0];
                const newY = currentNode.y + DIRECTIONS[i][1];
                
                if (!this.isValidMove(currentNode.x, currentNode.y, newX, newY)) {
                    continue;
                }
                
                const newNodeIndex = this.getNodeIndex(newX, newY);
                const neighborNode = this.nodes[newNodeIndex];
                
                // 检查是否已访问
                if (neighborNode.visited === 2) {
                    continue;
                }
                
                // 计算新的G值
                const directionChangeCost = this.calculateDirectionChangeCost(currentNode, i);
                const newG = currentNode.G + (i < 4 ? DIAGONAL_COST : STRAIGHT_COST) + directionChangeCost;
                
                // 如果是新节点或找到更好的路径
                if (neighborNode.visited === 0 || newG < neighborNode.G) {
                    neighborNode.x = newX;
                    neighborNode.y = newY;
                    neighborNode.G = newG;
                    neighborNode.H = this.calculateH(newX, newY, endX, endY);
                    neighborNode.F = neighborNode.G + neighborNode.H;
                    neighborNode.parent = currentNode;
                    neighborNode.direction = i;

                    if (neighborNode.visited === 0) {
                        neighborNode.visited = 1;
                        this.addToOpenList(neighborNode);
                    }
                }
            }
        }

        if (iterations >= this.maxIterations) {
            self.postMessage("message_寻路结束: 失败 - 达到最大迭代次数限制");
        } else {
            self.postMessage("message_寻路结束: 失败 - 开放列表为空，无法找到有效路径");
        }

        return null;
    }
}

// 添加 Worker 包装函数
let astarInstance = null;

// 初始化 A* 实例
/**function initAStar(width, height, gridData) {
    try {
        astarInstance = new AStar(width, height);
        if (gridData) {
            astarInstance.updateGrid(new Int32Array(gridData));
        }
        return { success: true };
    } catch (error) {
        return { 
            success: false, 
            error: `初始化失败: ${error.message}` 
        };
    }
}

// 更新地图数据
function updateGrid(gridData) {
    if (!astarInstance) {
        return { 
            success: false, 
            error: 'A* 实例未初始化' 
        };
    }
    try {
        astarInstance.updateGrid(new Int32Array(gridData));
        return { success: true };
    } catch (error) {
        return { 
            success: false, 
            error: `更新地图失败: ${error.message}` 
        };
    }
}

// 寻路
function findPath(startX, startY, endX, endY) {
    if (!astarInstance) {
        return { 
            success: false, 
            error: 'A* 实例未初始化' 
        };
    }
    try {
        const path = astarInstance.findPath(startX, startY, endX, endY);
        return {
            success: true,
            path: path
        };
    } catch (error) {
        return { 
            success: false, 
            error: `寻路失败: ${error.message}` 
        };
    }
}

// 设置障碍物
function setObstacle(x, y) {
    if (!astarInstance) {
        return { 
            success: false, 
            error: 'A* 实例未初始化' 
        };
    }
    try {
        const index = astarInstance.getNodeIndex(x, y);
        if (index >= 0 && index < astarInstance.grid.length) {
            astarInstance.grid[index] = 1;
            return { success: true };
        }
        return { 
            success: false, 
            error: '坐标超出范围' 
        };
    } catch (error) {
        return { 
            success: false, 
            error: `设置障碍物失败: ${error.message}` 
        };
    }
}

// 清除障碍物
function clearObstacle(x, y) {
    if (!astarInstance) {
        return { 
            success: false, 
            error: 'A* 实例未初始化' 
        };
    }
    try {
        const index = astarInstance.getNodeIndex(x, y);
        if (index >= 0 && index < astarInstance.grid.length) {
            astarInstance.grid[index] = 0;
            return { success: true };
        }
        return { 
            success: false, 
            error: '坐标超出范围' 
        };
    } catch (error) {
        return { 
            success: false, 
            error: `清除障碍物失败: ${error.message}` 
        };
    }
}**/

// 处理 Worker 消息
self.onmessage = function(event) {
    const data = event.data;
    const myType = data[7];  // 命令类型
    const blockData = data[0];  // 地图数据（二维数组）
    const width = data[1];  // 地图宽度
    const height = data[2];  // 地图高度
    const startX = data[3];  // 起点X
    const startY = data[4];  // 起点Y
    const endX = data[5];    // 终点X
    const endY = data[6];    // 终点Y

    self.postMessage("message_Worker收到消息, 类型=" + myType);

    try {
        if (myType === "astarUpdateData") {
            // 更新地图数据
            if (!astarInstance) {
                // 如果实例不存在，先创建
                astarInstance = new AStar(width, height);
            }
            // 直接传入二维数组
            astarInstance.updateGrid(blockData, width, height);
            self.postMessage("message_地图更新成功");
        }
        else if (myType === "astarFindRoad") {
            // 寻路
            if (!astarInstance) {
                throw new Error("A* 实例未初始化");
            }

            self.postMessage("message_Worker开始寻路");
            const path = astarInstance.findPath(startX, startY, endX, endY);
            self.postMessage("message_Worker寻路完成");
            
            // 直接返回路径结果
            self.postMessage(path);
        }
        else {
            console.error("Worker未知的命令类型:", myType);
            self.postMessage(null);
        }
    } catch (error) {
        console.error('Worker操作错误:', error);
        self.postMessage(null);
    }
};

// 添加定期内存检查
/**setInterval(() => {
    if (astarInstance) {
        self.postMessage("message_Worker定期内存检查：");
        // 这里可以添加内存使用统计
        const memoryUsage = {
            gridSize: astarInstance.grid.length * 4,  // Int32Array 每个元素4字节
            nodesSize: astarInstance.nodes.length * 8,  // 粗略估计每个节点对象的大小
            openListSize: astarInstance.openListCount * 8  // 粗略估计开放列表的大小
        };
        self.postMessage("message_内存使用情况:", memoryUsage);
    }
}, 5000);  // 每5秒检查一次
**/


// 导出类（保留原有的导出，以便其他模块使用）
//export default AStar; 